///
/// @file SimpleRegisterAllocator.h
/// @brief 简单或朴素的寄存器分配器
/// @author zenglj (zenglj@live.com)
/// @version 1.0
/// @date 2024-09-29
///
/// @copyright Copyright (c) 2024
///
/// @par 修改日志:
/// <table>
/// <tr><th>Date       <th>Version <th>Author  <th>Description
/// <tr><td>2024-09-29 <td>1.0     <td>zenglj  <td>新建
/// </table>
///
#pragma once

#include <vector>

#include "BitMap.h"
#include "Value.h"
#include "PlatformArm64.h"

// 添加前向声明解决循环依赖问题
class ILocArm64;

class SimpleRegisterAllocator {
public:
    SimpleRegisterAllocator();

    // 整型寄存器分配与释放
    int AllocateInt(Value * var = nullptr, int32_t no = -1);
    void AllocateInt(int32_t no);
    void freeInt(Value * var);
    void freeInt(int32_t);
    void bitmapSet(int32_t no);

    // 浮点寄存器分配与释放
    int AllocateFloat(Value * var = nullptr, int32_t no = -1);
    void AllocateFloat(int32_t no);
    void freeFloat(Value * var);
    void freeFloat(int32_t);
    void floatBitmapSet(int32_t no);

    // 统一接口
    int Allocate(bool is_float = false, Value * var = nullptr, int32_t no = -1);
    void AllocateReg(int32_t no, bool is_float = false);
    void free(Value * var, bool is_float = false);
    void free(int32_t no, bool is_float = false);

    // 检查寄存器是否被使用
    bool isRegisterUsed(int32_t regno) const
    {
        return regno >= 0 && regno < PlatformArm64::maxRegNum && regBitmap.test(regno);
    }

    // 检查浮点寄存器是否被使用
    bool isFloatRegisterUsed(int32_t regno) const
    {
        return regno >= 0 && regno < PlatformArm64::maxRegNum && floatRegBitmap.test(regno);
    }

    // 获取当前活跃的整型寄存器位图
    const BitMap<PlatformArm64::maxUsableRegNum> & getIntRegisterBitmap() const
    {
        return regBitmap;
    }

    // 获取当前活跃的浮点寄存器位图
    const BitMap<PlatformArm64::maxUsableFloatNum> & getFloatRegisterBitmap() const
    {
        return floatRegBitmap;
    }

    int saveActiveRegisters(ILocArm64 & iloc);
    void restoreActiveRegisters(ILocArm64 & iloc, int stackSize);

protected:
    // 整型寄存器
    BitMap<PlatformArm64::maxUsableRegNum> regBitmap;
    std::vector<Value *> regValues;
    BitMap<PlatformArm64::maxUsableRegNum> usedBitmap;
    int32_t currentReg = 0;

    // 浮点寄存器
    BitMap<PlatformArm64::maxUsableFloatNum> floatRegBitmap;
    std::vector<Value *> floatRegValues;
    BitMap<PlatformArm64::maxUsableFloatNum> floatUsedBitmap;
    int32_t currentFloatReg = 0;
};
